package com.ruoyi.web.controller.erpbase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.SaleOrPurchType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.flowable.service.IFlowDefinitionService;
import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.system.domain.ApprovalConfig;
import com.ruoyi.system.domain.FlowProcDefDto;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.Funds;
import com.ruoyi.system.service.IApprovalConfigService;
import com.ruoyi.system.service.IFundsService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 账户管理Controller
 * 
 * @author he
 * @date 2025-10-20
 */
@RestController
@RequestMapping("/system/funds")
public class FundsController extends BaseController
{
    @Autowired
    private IFundsService fundsService;

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Autowired
    private IFlowTaskService flowTaskService;

    @Autowired
    private IApprovalConfigService approvalConfigService;

    /**
     * 查询账户管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:funds:list')")
    @GetMapping("/list")
    public TableDataInfo list(Funds funds)
    {
        startPage();
        List<Funds> list = fundsService.selectFundsList(funds);
        return getDataTable(list);
    }

    /**
     * 导出账户管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:funds:export')")
    @Log(title = "账户管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Funds funds)
    {
        List<Funds> list = fundsService.selectFundsList(funds);
        ExcelUtil<Funds> util = new ExcelUtil<Funds>(Funds.class);
        util.exportExcel(response, list, "账户管理数据");
    }

    /**
     * 获取账户管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:funds:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(fundsService.selectFundsById(id));
    }

    /**
     * 新增账户管理
     */
    @PreAuthorize("@ss.hasPermi('system:funds:add')")
    @Log(title = "账户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Funds funds)
    {
        return toAjax(fundsService.insertFunds(funds));
    }

    /**
     * 修改账户管理
     */
    @PreAuthorize("@ss.hasPermi('system:funds:edit')")
    @Log(title = "账户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Funds funds)
    {
        return toAjax(fundsService.updateFunds(funds));
    }

    /**
     * 删除账户管理
     */
    @PreAuthorize("@ss.hasPermi('system:funds:remove')")
    @Log(title = "账户管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(fundsService.deleteFundsByIds(ids));
    }

    /**
     * 获取账户信息列表(用于下拉框)
     */
    @PreAuthorize("@ss.hasPermi('system:funds:list')")
    @PostMapping("/getFundsInfoList")
    public AjaxResult getFundsInfoList(Funds funds)
    {
        List<Funds> list = fundsService.selectFundsList(funds);
        return success(list);
    }

    /**
     * 批量发起账户管理审批
     */
    @Log(title = "账户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalStart")
    public AjaxResult approvalStart(@RequestBody List<Long> ids)
    {
        if (!approvalConfigService.isModuleEnabled("funds")) {
            return error("账户管理模块未启用审批流，请先在审批配置中启用");
        }

        ApprovalConfig config = approvalConfigService.selectByModuleCode("funds");
        String flowName = config != null && StringUtils.isNotEmpty(config.getFlowName()) 
                ? config.getFlowName() : "账户管理审核";

        List<Funds> allFunds = fundsService.selectFundsList(new Funds());
        
        List<Funds> fundsToApprove = new ArrayList<>();
        for (Funds fund : allFunds) {
            if (ids.contains(fund.getId())) {
                fundsToApprove.add(fund);
            }
        }

        if (CollectionUtils.isNotEmpty(fundsToApprove)) {
            Page<FlowProcDefDto> page = flowDefinitionService.list(flowName, 1, 10);
            List<FlowProcDefDto> records = page.getRecords();
            
            if (CollectionUtils.isEmpty(records)) {
                return error("未找到'" + flowName + "'流程定义，请先配置审批流程");
            }
            
            FlowProcDefDto flowProcDefDto = records.get(0);
            String deploymentId = flowProcDefDto.getDeploymentId();
            String flowId = flowProcDefDto.getId();
            AjaxResult ajaxResult1 = flowTaskService.flowFormData(deploymentId);

            Map<String, Object> variables = new HashMap<>();
            Object o = ajaxResult1.get("data");
            variables.put("formJson", o);

            List<Long> idsToUpdate = new ArrayList<>();
            for (Funds fund : fundsToApprove) {
                variables.put("id", fund.getId());
                variables.put("fundName", fund.getName());
                variables.put("residueAmount", fund.getResidueAmount());
                variables.put("creditAmount", fund.getCreditAmount());
                
                AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById(flowId, variables);
                if (ajaxResult.isSuccess()) {
                    idsToUpdate.add(fund.getId());
                }
            }

            if (CollectionUtils.isNotEmpty(idsToUpdate)) {
                fundsService.updateApprovalState(idsToUpdate, SaleOrPurchType.APPROVAL_YN.getCode());
            }
        }

        return toAjax(1);
    }

    /**
     * 审批流结束触发审核完成
     */
    @Log(title = "账户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalEnd")
    public AjaxResult approvalEnd(@RequestBody Long id)
    {
        fundsService.updateApprovalState(Arrays.asList(id), SaleOrPurchType.APPROVAL_YES.getCode());
        return toAjax(1);
    }
}
